package com.example.demo.util;

import com.example.demo.controller.Init;
import com.example.demo.controller.TableController;
import com.example.demo.enums.View;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author hweiyu
 * @Description
 * @Date 2022/6/27 16:33
 */
@SuppressWarnings("unchecked")
@Component
@Slf4j
public class NavUtil implements ApplicationContextAware {

    private static ConfigurableApplicationContext context;

    private static Map<String, Stage> stageMap = new HashMap<>();

    private static Map<String, Object> controllerMap = new HashMap<>();

    private static Map<String, Object> paramMap = new HashMap<>();

    public synchronized static Parent getView(View view) {
        FXMLLoader fxmlLoader = new FXMLLoader(NavUtil.class.getResource(view.getFxml()));
        fxmlLoader.setControllerFactory(context::getBean);
        try {
            return fxmlLoader.load();
        } catch (IOException e) {
            log.error("获取视图异常，path：{}", view.getFxml(), e);
        }
        return null;
    }

    public synchronized static void toPage(View view, Object param) {
        Stage stage = stageMap.get(view.getFxml());
        Object controller = controllerMap.get(view.getFxml());
        if (null == stage) {
            FXMLLoader fxmlLoader = new FXMLLoader(NavUtil.class.getResource(view.getFxml()));
            fxmlLoader.setControllerFactory(context::getBean);
            Parent pane = null;
            try {
                pane = fxmlLoader.load();
                Scene scene = new Scene(pane);
                stage = new Stage();
                stage.setScene(scene);
                stage.setTitle(view.getModule() + "->" + view.getTitle());
                stage.initStyle(StageStyle.DECORATED);
                //仅当前页面可以编辑
                stage.initModality(Modality.APPLICATION_MODAL);
                stageMap.put(view.getFxml(), stage);
                //控制器
                controller = fxmlLoader.getController();
                controllerMap.put(view.getFxml(), controller);
            } catch (IOException e) {
                log.error("跳转异常，path：{}", view.getFxml(), e);
            }
        }
        if (null != stage) {
            stage.show();
            if (null != param) {
                paramMap.put(view.getFxml(), param);
            }
            if (null != controller) {
                //调用控制器的init方法
                if (controller instanceof Init) {
                    ((Init) controller).init();
                }
            }
        }
    }

    public synchronized static void close(View view) {
        Stage stage = stageMap.get(view.getFxml());
        if (null != stage) {
            stage.close();
            stageMap.remove(view.getFxml());
            controllerMap.remove(view.getFxml());
            paramMap.remove(view.getFxml());
        }
    }

    public synchronized static void refreshTableView(View view) {
        if (null == view.getController()) {
            return;
        }
        Object controller = context.getBean(view.getController());
        if (controller instanceof TableController) {
            ((TableController) controller).refreshTable();
        }
    }

    public synchronized static <T> T getParameter(View view) {
        return (T) paramMap.get(view.getFxml());
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        NavUtil.context = (ConfigurableApplicationContext) applicationContext;
    }
}
